package com.manager.core.module.manager.service;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import com.manager.commons.log.LogFactory;
import com.manager.gen.module.LoginController;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.mgt.DefaultSessionManager;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.google.code.kaptcha.Constants;
import com.manager.commons.Constant;
import com.manager.commons.encrypt.md5.MD5;
import com.manager.commons.utils.DateUtil;
import com.manager.commons.utils.IPUtil;
import com.manager.commons.utils.StringUtil;
import com.manager.gen.module.platform.core.dao.PlatformUserDao;
import com.manager.gen.module.platform.core.entity.PlatformUser;
import com.manager.core.shiro.config.ShiroConfig;
import com.manager.core.shiro.config.ShiroUtil;
import com.manager.core.shiro.core.dao.ShiroDao;
import com.manager.core.shiro.core.entity.LoginUser;
import com.manager.core.shiro.core.entity.ShiroUserRole;
import com.manager.core.web.json.AjaxJson;

@Service
public class LoginService {
    protected static final Logger logger = LogFactory.getLogger(LoginController.class);
    @Autowired
    private PlatformUserDao puDao;
    @Autowired
    private ShiroDao shiroDao;

    /**
     * 登录
     *
     * @param account
     * @return
     */
    private PlatformUser login(String account) {
        return puDao.login(new HashMap<String, Object>() {
			private static final long serialVersionUID = 2897617740011146915L;
			{
                put("account", account);
            }
        });
    }

    /**
     * 插入日志
     *
     * @param summary
     * @param content
     * @param type
     * @param host
     * @param method
     * @param params
     * @param startTime
     * @param creator
     * @param request
     * @throws Exception
     */
    private void insertLog(String summary, String content, String type, String host, String method, String params,
                           String startTime, String creator, String puId, HttpServletRequest request) throws Exception {
        if (StringUtil.isEmpty(host)) {
            host = IPUtil.getIpAddr(request);
        }
        String userAgent = request.getHeader("User-Agent");
        String endTime = DateUtil.currentDateTime();
    }

    /**
     * 退出登录
     *
     * @param session
     * @param request
     * @param subject
     * @throws Exception
     */
    public void logout(HttpSession session, HttpServletRequest request, Subject subject) throws Exception {
        session.removeAttribute("");
        if (null != subject) {
            Object logOperator = session.getAttribute(Constant.LOG_OPERATOR);
            if (null != logOperator) {
                String startTime = DateUtil.currentDateTime();
                String pars = String.valueOf(logOperator);
                String[] params = pars.split("#");
                String content = String.format("用户：%s在%s退出系统。", params[1] + "【" + params[0] + "】", startTime);
                insertLog("用户退出", content, "mvp", "", "logout", pars, startTime, params[0], params[2], request);
            }
            subject.logout();
        }
    }


    /**
     * 登录
     *
     * @param user
     * @param session
     * @param request
     * @param subject
     * @return
     * @throws Exception
     */
    public AjaxJson doLogin(LoginUser user, HttpSession session, HttpServletRequest request, Subject subject) throws Exception {
        String startTime = DateUtil.currentDateTime();
        if (StringUtil.isBlank(user.getAccount())) {
            return new AjaxJson("用户名或密码错误！");
        }
        if (StringUtil.isBlank(user.getPassword())) {
            return new AjaxJson("用户名或密码错误！");
        }
        if (StringUtil.isBlank(user.getCode())) {
            return new AjaxJson("验证码错误！");
        }
        Object kskCode = session.getAttribute(Constants.KAPTCHA_SESSION_KEY);
        if (!user.getCode().equals(String.valueOf(kskCode))) {
            return new AjaxJson("验证码错误！");
        }
        int f = 0;
        String msg = "认证失败";
        String puId = null;
        String puName = "未知用户";
        String password = MD5.md5(user.getPassword());
        logger.debug(password+"----------------------------md5");
        UsernamePasswordToken token = new UsernamePasswordToken(user.getAccount(), password);
        // Shiro身份验证
        subject.login(token);
        String host = IPUtil.getIpAddr(request);
        if (subject.isAuthenticated()) {
            // 查询用户信息
            PlatformUser pu = login(user.getAccount());
            if (null != pu) {
                Map<String, Object> map = new HashMap<>();
                map.put("account", user.getAccount());
                ShiroUserRole role = shiroDao.queryUserRoles(map);
                if(role != null || user.getAccount().equals(ShiroConfig.superAdmin) ) {
                    session.setAttribute(ShiroConfig.CURRENTNAME, pu.getPuName());
                    if (user.getAccount().equals(ShiroConfig.superAdmin)) {
                        ShiroUtil.setCurrentRole(ShiroConfig.superAdmin, "超级管理员");
                    } else {
                        ShiroUtil.setCurrentRole(role.getRoleCode(), role.getRoleName());
                    }

                    f = 1;
                    msg = "登录成功";
                    // 验证码只使用一次，将验证码移除，防止复用
                    session.removeAttribute(Constants.KAPTCHA_SESSION_KEY);
                    puName = pu.getPuName();
                    puId = pu.get_id();
                    // 将用户存放在session中
                    puDao.updateLoginInfo(new HashMap<String, Object>() {
                        {
                            put("loginIp", host);
                            put("loginTime", DateUtil.currentDateTime());
                            put("_id", pu.get_id());
                        }
                    });
                    String content = String.format("用户：%s在%s登录系统，结果：%s。", puName + "【" + user.getAccount() + "】", startTime, msg);
                    insertLog("用户登录", content, "rmp", host, "doLogin", user.toString(), startTime, user.getAccount(), puId, request);
                }else{
                    return new AjaxJson(-1,"用户暂未进行角色授权，请联系管理员进行授权");
                }
            }
        }

        return new AjaxJson(f, msg);
    }

    /**
     * 遍历同一个账户的session
     *
     * @param currentUser
     * @return
     */
    protected List<Session> getLoginedSession(Subject currentUser) {
        Collection<Session> list = ((DefaultSessionManager) ((DefaultSecurityManager) SecurityUtils
                .getSecurityManager()).getSessionManager()).getSessionDAO().getActiveSessions();
        List<Session> loginedList = new ArrayList<Session>();
        String account = (String) currentUser.getPrincipal();
        for (Session session : list) {
            Subject s = new Subject.Builder().session(session).buildSubject();
            if (s.isAuthenticated()) {
                if (account.equals(s.getPrincipal())) {
                    if (!session.getId().equals(currentUser.getSession().getId())) {
                        loginedList.add(session);
                    }
                }
            }
        }
        return loginedList;
    }
}